Everything needed to build the back-office in Vue 3, vue-router, Pinia and Nuxt UI v4. Tokens have one source of truth, tokens/renewcms.css plus tokens/ui.config.ts. Components use PascalCase names and routes are kebab-case, matching the code.
A global router.beforeEach guard reads meta.auth. On the first navigation it resolves the session with GET /v1/auth/me (API pending) and caches the result in the session store. A fetch wrapper, useApi, turns any 401 into /login?redirect=&reason=expired and any 403 from an unverified account into /register/pending.
{{ r.p }}{{ r.l }}{{ r.a }}{{ r.s }}{{ r.api }}{{ c.b }}{{ c.p }}{{ c.e }}{{ c.s }}{{ c.u }}The composables behind these components are useSession, useApi, useArticles (the list cache plus actions shared by the table, cards and editor), useArticleDraft (dirty state, save, and the sessionStorage mirror), useImageUpload (XHR with progress) and useRetryAfter (429 countdown).
Every state is drawn at desktop and mobile on the auth and back-office boards, with final copy.
{{ m.r }}Response bodies are plain text and are never shown. useApi throws an ApiError with the status and a context key, and each screen maps them to the copy below.
{{ e.c }}{{ e.w }}{{ e.t }}{{ e.s }}{{ p.a }}{{ p.d }}